#include "app_pool.h"
#include "mqueue.h"
#include "pthread.h"
#include <stdlib.h>

#define MQ_LEN 10
#define MQ_MSG_SIZE sizeof(MQ_TASK_T)

char *mq_name = "/mq_pool"; // /表示路径：/dev/mqueue/
mqd_t mq_fd = -1 ; // 消息队列描述符

pthread_t *pool_threads = NULL;
int pool_thread_num = 0;

void *thread_func(void *arg)
{
    MQ_TASK_T task;
    while (1)
    {
        ssize_t len = mq_receive(mq_fd, (char *)&task, MQ_MSG_SIZE, NULL);
        if(len == MQ_MSG_SIZE)
        {
            task.mq_task(task.arg);
        }
    }
    
    return NULL;
}

int app_pool_init(int thread_num)
{
    // 1.创建消息队列
    struct  mq_attr attr = {
        .mq_maxmsg = MQ_LEN,
        .mq_msgsize = MQ_MSG_SIZE
    };    
    mq_fd = mq_open(mq_name, O_RDWR | O_CREAT, 0644, &attr);

    if(mq_fd == -1)
    {
        return -1;
    }

    // 2.创建线程池
    pool_thread_num = thread_num;
    pool_threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_num);
    for(int i = 0; i < thread_num; i++)
    {
        int res = pthread_create(&pool_threads[i], NULL, (void *)thread_func, NULL);
        if(res != 0)
        {
            return -1;
        }
    }

    return 0;
}

void app_pool_destroy(void)
{
    // 释放消息队列
    mq_close(mq_fd);
    mq_unlink(mq_name);

    // 释放线程池
    for(int i = 0; i < pool_thread_num; i++)
    {
        pthread_cancel(pool_threads[i]);
        pthread_join(pool_threads[i], NULL);
    }

    free(pool_threads);
}

int app_pool_registerMqTask(int (* mq_task)(void * arg), void * arg)
{
    MQ_TASK_T task = {
        .mq_task = mq_task,
        .arg = arg
    };

    mq_send(mq_fd, (char *)&task, MQ_MSG_SIZE, 0);


    return 0;
}
